package com.payment.controller.payment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.payment.entity.payment.oceanpay.request.RequestOceanPayment;
import com.payment.entity.payment.oceanpay.request.RequestOceanPaymentData;
import com.payment.entity.payment.oceanpay.request.RequestOceanPaymentTradeData;
import com.payment.entity.payment.oceanpay.response.ResponseOceanPayment;
import com.payment.entity.payment.oceanpay.response.ResponseOceanPaymentData;
import com.payment.entity.payment.oceanpay.response.ResponseOceanPaymentTradeData;
import com.payment.service.SequenceService;
import com.payment.utils.HMACSHA256;
import com.payment.utils.MD5;
import com.payment.utils.UtilsInterfacesPackage;
import com.payment.utils.payment.OceanPayConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@Api(description = "钱海信用卡支付")
/**
 * 1，使用领科的钱海收款接口，Paypal支付接口：
 *
 * 2，适用于新的客户：最新版的的领科 H5 和其他想要使用领科收款接口收款的（可以是客户自己的账号或者领科发账号）客户；
 *
 * 3，更新的数据表为：user_order_package_t，user_order_payment_t；
 *
 * 4，更新的数据库为：v-shop
 *
 * 5，很重要：现在已经废弃不再使用此种支付方式，接口废弃
 *
 * @author lm
 * @date 2019/11/06
 */
public class OceanPaymentController {
    private static Logger logger = Logger.getLogger(OceanPaymentController.class);
    @Autowired
    private SequenceService sequenceService;

    @PostMapping(value = "/oceanPay", produces = "application/json;charset=utf-8")
    @CrossOrigin
    @ResponseBody
    @ApiOperation(value = "钱海支付", response = ResponseOceanPayment.class)
    public String oceanPayment(@ApiParam @RequestBody RequestOceanPayment requestOceanPayment) throws Exception {
        // 1，生成流水号
        String connSeqNo = sequenceService.getPackageTaskNo();
        // 2,生成当前时间戳
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curtime = df.format(new Date());
        //3，定义回报报文
        String jsonString;
        UtilsInterfacesPackage utils = new UtilsInterfacesPackage();
        String requestStr = JSON.toJSONString(requestOceanPayment);
        if (requestStr == null) {
            logger.info("请求报文不合法:requestStr为空");
            jsonString = utils.dataWeiKong(connSeqNo, curtime);
            return jsonString;
        } else {
            logger.info("前端请求报文是：" + requestStr);
            RequestOceanPayment requestPackage = JSONArray.parseObject(requestStr, RequestOceanPayment.class);
            String requestSign = requestPackage.getSign();
            if (requestSign == null) {
                logger.info("请求报文不合法:sign为空");
                jsonString = utils.dataWeiKong(connSeqNo, curtime);
                return jsonString;
            } else {
                logger.info("请求的签名是：" + requestSign);
                RequestOceanPaymentData requestData = requestPackage.getData();
                if (requestData == null) {
                    logger.info("请求报文不合法:data为空");
                    jsonString = utils.dataWeiKong(connSeqNo, curtime);
                    return jsonString;
                } else {
                    String partnerCode = requestData.getPartnerCode();
                    String ConnSeqNo = requestData.getConnSeqNo();
                    String tradeTime = requestData.getTradeTime();
                    String tradeType = requestData.getTradeType();
                    String lang = requestData.getLang();
                    String version = requestData.getVersion();

                    RequestOceanPaymentTradeData requestTradeData = requestData.getTradeData();
                    if (requestTradeData == null || StringUtils.isBlank(partnerCode) || StringUtils.isBlank(ConnSeqNo) || StringUtils.isBlank(tradeTime) || StringUtils.isBlank(tradeType) || lang == null || version == null) {
                        logger.info("请求报文不合法:data参数不合法");
                        jsonString = utils.dataWeiKong(connSeqNo, curtime);
                        return jsonString;
                    } else {
                        String payAmount = requestTradeData.getPayAmount();
                        String payId = requestTradeData.getPayId();
                        String payCurrency = requestTradeData.getPayCurrency();
                        String backUrl = requestTradeData.getBackUrl();

                        String account = requestTradeData.getAccount();
                        String terminal = requestTradeData.getTerminal();
                        String secureCode = requestTradeData.getSecureCode();

                        if (StringUtils.isBlank(payAmount) || StringUtils.isBlank(payId) || StringUtils.isBlank(payCurrency) || StringUtils.isBlank(backUrl)) {
                            logger.info("请求报文不合法:orderId和amount不可以为空！");
                            jsonString = utils.dataWeiKong(connSeqNo, curtime);
                            return jsonString;
                        } else {
                            // 将请求体json转成String
                            String str = JSON.toJSONString(requestData);
                            // 将Str拿去计算签名
                            String sign = utils.calculateSignature(str);
                            logger.info("计算的签名是：" + sign);
                            if (!requestSign.equalsIgnoreCase(sign)) {
                                logger.info("签名验证失败！");
                                jsonString = utils.signatureFailure(ConnSeqNo, partnerCode, tradeTime, tradeType);
                                return jsonString;
                            } else {
                                //给前端准备需要的数据：
                                ResponseOceanPaymentTradeData tradeData = new ResponseOceanPaymentTradeData();

                                if (StringUtils.isBlank(account) || StringUtils.isBlank(terminal) || StringUtils.isBlank(secureCode)) {
                                    //使用默认领科的账户付款
                                    String ACCOUNT = OceanPayConstants.OceanPayaccount;
                                    String TERMINAL = OceanPayConstants.OceanPayterminal;
                                    String SECURECODE = OceanPayConstants.secureCode;
                                    String NOTIVEURL = OceanPayConstants.OceanPaynoticeUrl;
                                    String PAYMETHODS = OceanPayConstants.OceanPaymethods;
                                    String FIRST = OceanPayConstants.billing_firstName;
                                    String LAST = OceanPayConstants.billing_lastName;
                                    String EMAIL = OceanPayConstants.billing_email;
                                    String PHONE = OceanPayConstants.billing_phone;
                                    String COUNTRY = OceanPayConstants.billing_country;
                                    String CITY = OceanPayConstants.billing_city;
                                    String ADDRESS = OceanPayConstants.billing_address;
                                    String ZIP = OceanPayConstants.billing_zip;

                                    String signStr = SignValue(ACCOUNT, TERMINAL, backUrl, payId, payCurrency, payAmount, FIRST, LAST, EMAIL, SECURECODE);
                                    tradeData.setAccount(ACCOUNT);
                                    tradeData.setTerminal(TERMINAL);
                                    tradeData.setSignValue(signStr);
                                    tradeData.setBackUrl(backUrl);
                                    tradeData.setNoticeUrl(NOTIVEURL);
                                    tradeData.setMethods(PAYMETHODS);
                                    tradeData.setOrder_number(payId);
                                    tradeData.setOrder_currency(payCurrency);
                                    tradeData.setOrder_amount(payAmount);
                                    tradeData.setBilling_firstName(FIRST);
                                    tradeData.setBilling_lastName(LAST);
                                    tradeData.setBilling_email(EMAIL);
                                    tradeData.setBilling_phone(PHONE);
                                    tradeData.setBilling_country(COUNTRY);
                                    tradeData.setBilling_city(CITY);
                                    tradeData.setBilling_address(ADDRESS);
                                    tradeData.setBilling_zip(ZIP);

                                } else {
                                    //使用客户的oceanpay账户付款
                                    String NOTIVEURL = OceanPayConstants.OceanPaynoticeUrl;
                                    String PAYMETHODS = OceanPayConstants.OceanPaymethods;
                                    String FIRST = OceanPayConstants.billing_firstName;
                                    String LAST = OceanPayConstants.billing_lastName;
                                    String EMAIL = OceanPayConstants.billing_email;
                                    String PHONE = OceanPayConstants.billing_phone;
                                    String COUNTRY = OceanPayConstants.billing_country;
                                    String CITY = OceanPayConstants.billing_city;
                                    String ADDRESS = OceanPayConstants.billing_address;
                                    String ZIP = OceanPayConstants.billing_zip;
                                    String signStr = SignValue(account, terminal, backUrl, payId, payCurrency, payAmount, FIRST, LAST, EMAIL, secureCode);

                                    tradeData.setAccount(account);
                                    tradeData.setTerminal(terminal);
                                    tradeData.setSignValue(signStr);
                                    tradeData.setBackUrl(backUrl);
                                    tradeData.setNoticeUrl(NOTIVEURL);
                                    tradeData.setMethods(PAYMETHODS);
                                    tradeData.setOrder_number(payId);
                                    tradeData.setOrder_currency(payCurrency);
                                    tradeData.setOrder_amount(payAmount);
                                    tradeData.setBilling_firstName(FIRST);
                                    tradeData.setBilling_lastName(LAST);
                                    tradeData.setBilling_email(EMAIL);
                                    tradeData.setBilling_phone(PHONE);
                                    tradeData.setBilling_country(COUNTRY);
                                    tradeData.setBilling_city(CITY);
                                    tradeData.setBilling_address(ADDRESS);
                                    tradeData.setBilling_zip(ZIP);
                                }

                                //准备data
                                ResponseOceanPaymentData data = new ResponseOceanPaymentData();
                                data.setConnSeqNo(ConnSeqNo);
                                data.setPartnerCode(partnerCode);
                                data.setTradeType(tradeType);
                                data.setTradeTime(tradeTime);
                                data.setTradeRstCode("0000");
                                if (lang.equals("cn") || StringUtils.isBlank(lang)) {
                                    data.setTradeRstMessage("成功");
                                } else {
                                    data.setTradeRstMessage("success");
                                }
                                data.setTradeData(tradeData);

                                ResponseOceanPayment responseWeiXinPay = new ResponseOceanPayment();
                                responseWeiXinPay.setData(data);
                                responseWeiXinPay.setSign(MD5.calcMD5(JSON.toJSONString(data)));
                                // 返回给调用者的报文
                                jsonString = JSON.toJSONString(responseWeiXinPay);
                                logger.info("响应报文：" + jsonString);
                                return jsonString;

                            }
                        }
                    }
                }
            }
        }
    }

    /***
     * 计算签名
     * @param payId
     * @param payCurrency
     * @param payAmount
     * @param billing_firstName
     * @param billing_lastName
     * @param billing_email
     * @param secureCode
     * @return
     */
    public String SignValue(String account, String terminal, String backUrl, String payId, String payCurrency, String payAmount, String billing_firstName, String billing_lastName, String billing_email, String secureCode) {
        // 专门用于签名拼接使用
        StringBuffer buffer1 = new StringBuffer();
        buffer1.append(account);
        buffer1.append(terminal);
        buffer1.append(backUrl);
        buffer1.append(payId);
        buffer1.append(payCurrency);
        buffer1.append(payAmount);
        buffer1.append(billing_firstName);
        buffer1.append(billing_lastName);
        buffer1.append(billing_email);
        buffer1.append(secureCode);
        String str1 = buffer1.toString();
        System.out.println(str1);
        //String sign = HMACSHA256.sha256_HMAC(str1, secureCode);
        String sign = HMACSHA256.getSHA256StrJava(str1);
        return sign;

    }
}